/************************************
 * Package: RGcpp					*
 * Authors: Rui Eduardo Gouveia Gil	*
 * Date: 2010						*
 ************************************/
#include "rgcpp/tools/StringTokenizer.h"

namespace rgcpp
{

StringTokenizer::StringTokenizer()
{
	this->del = ' ';
	this->str = "";
	this->current = 0;
	this->strTokens = "";
	this->elementsCount = 0;
}

StringTokenizer::StringTokenizer(const std::string& str)
{
	this->del = ' ';
	this->str = str;
	this->current = 0;
	this->strTokens = str;
	this->elementsCount = 0;

	if(str.size())
		elementsCount++;

	for(std::string::const_iterator i=str.begin(); i!=str.end(); i++)
		if(*i==del && (i+1)!=str.end())
			elementsCount++;
}

StringTokenizer::StringTokenizer(const std::string& str, char del)
{
	this->del = del;
	this->str = str;
	this->current = 0;
	this->strTokens = str;
	this->elementsCount = 0;

	if(str.size())
		elementsCount++;

	for(std::string::const_iterator i=str.begin(); i!=str.end(); i++)
		if(*i==del && (i+1)!=str.end())
			elementsCount++;
}

StringTokenizer::StringTokenizer(const StringTokenizer& copy)
{
	this->del = copy.del;
	this->str = copy.str;
	this->current = copy.current;
	this->strTokens = copy.strTokens;
	this->elementsCount = copy.elementsCount;
}

StringTokenizer::~StringTokenizer()
{

}

bool StringTokenizer::hasMoreElements()
{
	boost::mutex::scoped_lock lock(mut);
	return (elementsCount!=current);
}

std::string StringTokenizer::nextToken()
{
	boost::mutex::scoped_lock lock(mut);

	if(elementsCount==current)
	{
		Throw(NoMoreElementsException("No More Element"));
	}

	current++;

	unsigned int pos = str.find(del);

	std::string result = str.substr(0,pos);
	str = str.substr(pos+1);

	return result;
}

int StringTokenizer::nextTokenInt()
{
	boost::mutex::scoped_lock lock(mut);

	if(elementsCount==current)
	{
		Throw(NoMoreElementsException("No More Element"));
	}

	current++;

	unsigned int pos = str.find(del);

	std::string result = str.substr(0,pos);
	str = str.substr(pos+1);

	return atoi(result.c_str());
}

float StringTokenizer::nextTokenFloat()
{
	boost::mutex::scoped_lock lock(mut);

	if(elementsCount==current)
	{
		Throw(NoMoreElementsException("No More Element"));
	}

	current++;

	unsigned int pos = str.find(del);

	std::string result = str.substr(0,pos);
	str = str.substr(pos+1);

	return (float)atof(result.c_str());
}

unsigned int StringTokenizer::countTokens()
{
	boost::mutex::scoped_lock lock(mut);
	return elementsCount;
}

unsigned int StringTokenizer::countRemainingTokens()
{
	boost::mutex::scoped_lock lock(mut);
	return elementsCount-current;
}

void StringTokenizer::reset()
{
	boost::mutex::scoped_lock lock(mut);
	current=0;
	str=strTokens;
}

}
